package org.ims.inv.model.project;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.ims.inv.model.system.ModelAppDictionary;
import org.ims.inv.model.system.ModelAppUser;
import org.ims.inv.vo.VoProjectCond;

import cn.trymore.core.bean.PairObject;
import cn.trymore.core.model.ModelBase;
import cn.trymore.core.util.UtilCollection;
import cn.trymore.core.util.UtilString;

/**
 * Model: 项目
 * 
 * @author Jeccy.Zhao
 *
 */
public class ModelProject
extends ModelBase
{
	/**
	 * SerialUID
	 */
	private static final long serialVersionUID = -2371813634797190650L;
	
	/**
	 * 项目编号
	 */
	private String projectNo;
	
	/**
	 * 项目名称
	 */
	private String projectName;
	
	/**
	 * 项目行业
	 */
	private ModelAppDictionary projectType;
	
	/**
	 * 项目推荐日期
	 */
	private Date projectRecommendedDate;
	
	/**
	 * 项目推荐人
	 */
	private ModelAppUser projectReferral;
	
	/**
	 * 其他项目推荐人名称
	 */
	private String projectReferralName;
	
	/**
	 * 项目发明人
	 */
	private String projectInventor;
	
	/**
	 * 项目发明人联系方式
	 */
	private String projectInventorContact;
	
	/**
	 * 项目经理
	 */
	private ModelAppUser projectManager;
	
	/**
	 * 项目参与人员
	 */
	private String projectAttendeeIds;
	
	/**
	 * 项目合作方类型
	 */
	private ModelAppDictionary projectPartnerType;
	
	/**
	 * 项目合作方名称
	 */
	private String projectPartnerName;
	
	/**
	 * 项目合作方参与人员
	 */
	private String projectPartnerAttendeeIds;
	
	/**
	 * 项目摘要
	 */
	private String projectSummary;
	
	/**
	 * 项目备注
	 */
	private String projectMeto;
	
	/**
	 * 项目登记人员
	 */
	private ModelAppUser projectRecorder;
	
	/**
	 * 项目登记时间
	 */
	private Date projectCreationTime;
	
	/**
	 * 项目可见范围
	 */
	private Integer projectVisibleRange;
	
	/**
	 * 项目状态: 
	 * 
	 * -2: 储备项目, -1: 审批退回, 0: 待提交材料, 1: 审批中,  2: 已否决, 3: 已立项 
	 */
	private Integer projectStatus;
	
	/**
	 * 项目材料
	 */
	private Set<ModelProjectMaterial> materials;
	
	/**
	 * 审批流程表单
	 */
	private Set<ModelProjectProcess> processForms;
	
	/**
	 * 审批流程历史事件
	 */
	private Set<ModelProjectEvent> processEvents;
	
	/**
	 * 当前项目进展
	 */
	private ModelProjectProcess currentProcess;
	
	/**
	 * 项目提交时间
	 */
	private Date projectPostTime;
	
	/**
	 * 暂停原因
	 */
	private String suspendReason;
	
	/**
	 * 暂停时间
	 */
	private Date suspendTime;
	
	/**
	 * 储备项目标志
	 */
	private Integer archived;
	
	/**
	 * 查询VO
	 */
	private VoProjectCond condVO = new VoProjectCond();
	
	/**
	 * 临时变量, 主要用于进行项目编号年份匹配搜索
	 */
	private String condYearMatch;
	
	/**
	 * 临时变量, 主要用于查询时是否对项目参与人员是否被包含
	 */
	private boolean isRelevantPersonIncluded;
	
	/**
	 * The enumeration of project status
	 * 
	 * @author Jeccy.Zhao
	 *
	 */
	public static enum EProjectStatus
	{
		SUSPENDED(-2, "suspend"),				// 暂停项目
		RETURNED(-1, "returned"),				// 审核退回
		TOPOST(0, "topost"),					// 待提交材料
		APPROVING(1, "approving"),				// 审批中
		REJECTED(2, "rejected"),				// 已否决
		APPROVED(3, "approved");				// 已立项
		
		private Integer value;
		private String text;
		
		EProjectStatus (Integer value, String text)
		{
			this.value = value;
			this.text = text;
		}
		
		public Integer getValue(){
			return value;
		}
		
		public String getText()
		{
			return this.text;
		}
	}
	
	/**
	 * The enumeration of project archive status
	 * 
	 * @author Jeccy.Zhao
	 *
	 */
	public static enum EProjectArchived
	{
		WESTAGED(0, "westaged"),				// 已流失
		ARCHIEVED(1, "archived");				// 已储备
		
		private Integer value;
		private String text;
		
		EProjectArchived (Integer value, String text)
		{
			this.value = value;
			this.text = text;
		}
		
		public Integer getValue(){
			return value;
		}
		
		public String getText()
		{
			return this.text;
		}
	}
	
	/**
	 * The enumeration of project visible range
	 * 
	 * @author Jeccy.Zhao
	 *
	 */
	public static enum EProjectVisible
	{
		PUBLIC(0, "public"),				// 公司内部公开
		INTERNAL(1, "internal"),			// 项目内部公开
		LEADERSHIP(2, "leadership");		// 项目高层公开
		
		private Integer value;
		private String text;
		
		EProjectVisible (Integer value, String text)
		{
			this.value = value;
			this.text = text;
		}
		
		public Integer getValue(){
			return value;
		}
		
		public String getText()
		{
			return this.text;
		}
	}
	
	/**
	 * 根据offset获取审批流程环节
	 * 
	 * @param offset
	 * @return
	 */
	public ModelProjectProcess getProcessByOffset (int offset)
	{
		if (UtilCollection.isNotEmpty(this.getProcessForms()))
		{
			int startPos = 0;
			if (currentProcess == null)
			{
				startPos = 1;
			}
			else
			{
				startPos = currentProcess.getSequence() + offset;
			}
			
			int count = 1;
			for (ModelProjectProcess process : this.getProcessForms())
			{
				if (count == startPos)
				{
					return process;
				}
				
				count++;
			}
		}
		
		return null;
	}
	
	/**
	 * 获取必须材料信息, 格式为: 已提交 / 需提交
	 * 
	 * @return
	 */
	public PairObject<Integer, Integer> getMandatoryMaterialInfo ()
	{
		PairObject<Integer, Integer> info = new PairObject<Integer, Integer>(0, 0);
		
		if (UtilCollection.isNotEmpty(this.getMaterials()))
		{
			for (ModelProjectMaterial material : this.materials)
			{
				getMandatoryMaterialInfo(material, info);
			}
		}
		
		return info;
	}
	

	/**
	 * 获取单个必须材料信息, 格式为: 已提交 / 需提交
	 * 
	 * @return
	 */
	private void getMandatoryMaterialInfo (ModelProjectMaterial material,
			PairObject<Integer, Integer> info)
	{
		if (UtilCollection.isNotEmpty(material.getMaterialChildren()))
		{
			for (ModelProjectMaterial node : material.getMaterialChildren())
			{
				this.getMandatoryMaterialInfo(node, info);
			}
		}
		
		if (material.getMaterialType() != null && material.getMaterialType().equals(1))
		{
			info.setRight(info.getRight() + 1);
			
			if (UtilCollection.isNotEmpty(material.getMetas()))
			{
				info.setLeft(info.getLeft() + 1);
			}
		}
		
	}
	
	/**
	 * 获取必须材料列表
	 * 
	 * @param exculdeEmptyEntity
	 * @return
	 */
	public List<ModelProjectMaterial> getMandatoryMaterialList (
			boolean exculdeEmptyEntity)
	{
		if (UtilCollection.isNotEmpty(this.materials))
		{
			List<ModelProjectMaterial> result = new ArrayList<ModelProjectMaterial>();
			
			for (ModelProjectMaterial material : this.materials)
			{
				if (material.getMaterialType() != null && material.getMaterialType().equals(1))
				{
					if (exculdeEmptyEntity &&  material.getLatestUploadMeta() == null)
					{
						continue;
					}
					
					result.add(material);
				}
				
				if (UtilCollection.isNotEmpty(material.getMaterialChildren()))
				{
					for (ModelProjectMaterial child : material.getMaterialChildren())
					{
						if (child.getMaterialType() != null && child.getMaterialType().equals(1))
						{
							if (exculdeEmptyEntity &&  child.getLatestUploadMeta() == null)
							{
								continue;
							}
							
							result.add(child);
						}
					}
				}
				
			}
			
			return result;
		}
		
		return null;
	}
	
	/**
	 * 获取最新项目事件
	 * 
	 * @return
	 */
	public ModelProjectEvent getLastestEvent()
	{
		if (UtilCollection.isNotEmpty(this.processEvents))
		{
			int count = 0;
			for (ModelProjectEvent event : this.processEvents)
			{
				if (count == this.processEvents.size() - 1)
				{
					return event;
				}
				
				count++;
			}
		}
		
		return  null;
	}
	
	public String getProjectRelevantPersonIds()
	{
		List<String> uids = this.getRelevantPersonIds();
		
		String result = UtilString.join(uids, ",");
		
		uids.clear();
		uids = null;
		
		return result;
	}
	
	public List<String> getRelevantPersonIds()
	{
		List<String> uids = new ArrayList<String>();
		
		if (this.projectManager != null)
		{
			uids.add(this.projectManager.getId());
		}
		
		if (UtilString.isNotEmpty(this.projectAttendeeIds))
		{
			String[] aids = this.projectAttendeeIds.split(",");
			for (String id : aids)
			{
				if (!uids.contains(id))
				{
					uids.add(id);
				}
			}
		}
		
		return uids;
	}
	
	public String getProjectName()
	{
		return projectName;
	}

	public void setProjectName(String projectName)
	{
		this.projectName = projectName;
	}

	public ModelAppDictionary getProjectType()
	{
		return projectType;
	}

	public void setProjectType(ModelAppDictionary projectType)
	{
		this.projectType = projectType;
	}

	public Date getProjectRecommendedDate()
	{
		return projectRecommendedDate;
	}

	public void setProjectRecommendedDate(Date projectRecommendedDate)
	{
		this.projectRecommendedDate = projectRecommendedDate;
	}

	public ModelAppUser getProjectReferral()
	{
		return projectReferral;
	}

	public void setProjectReferral(ModelAppUser projectReferral)
	{
		this.projectReferral = projectReferral;
	}

	public String getProjectInventorContact()
	{
		return projectInventorContact;
	}

	public void setProjectInventorContact(String projectInventorContact)
	{
		this.projectInventorContact = projectInventorContact;
	}

	public ModelAppUser getProjectManager()
	{
		return projectManager;
	}

	public void setProjectManager(ModelAppUser projectManager)
	{
		this.projectManager = projectManager;
	}

	public String getProjectAttendeeIds()
	{
		return projectAttendeeIds;
	}

	public void setProjectAttendeeIds(String projectAttendeeIds)
	{
		this.projectAttendeeIds = projectAttendeeIds;
	}

	public ModelAppDictionary getProjectPartnerType()
	{
		return projectPartnerType;
	}

	public void setProjectPartnerType(ModelAppDictionary projectPartnerType)
	{
		this.projectPartnerType = projectPartnerType;
	}

	public String getProjectPartnerName()
	{
		return projectPartnerName;
	}

	public void setProjectPartnerName(String projectPartnerName)
	{
		this.projectPartnerName = projectPartnerName;
	}

	public String getProjectPartnerAttendeeIds()
	{
		return projectPartnerAttendeeIds;
	}

	public void setProjectPartnerAttendeeIds(String projectPartnerAttendeeIds)
	{
		this.projectPartnerAttendeeIds = projectPartnerAttendeeIds;
	}

	public String getProjectSummary()
	{
		return projectSummary;
	}

	public void setProjectSummary(String projectSummary)
	{
		this.projectSummary = projectSummary;
	}

	public String getProjectMeto()
	{
		return projectMeto;
	}

	public void setProjectMeto(String projectMeto)
	{
		this.projectMeto = projectMeto;
	}

	public ModelAppUser getProjectRecorder()
	{
		return projectRecorder;
	}

	public void setProjectRecorder(ModelAppUser projectRecorder)
	{
		this.projectRecorder = projectRecorder;
	}

	public Date getProjectCreationTime()
	{
		return projectCreationTime;
	}

	public void setProjectCreationTime(Date projectCreationTime)
	{
		this.projectCreationTime = projectCreationTime;
	}

	public Integer getProjectVisibleRange()
	{
		return projectVisibleRange;
	}

	public void setProjectVisibleRange(Integer projectVisibleRange)
	{
		this.projectVisibleRange = projectVisibleRange;
	}

	public void setProjectStatus(Integer projectStatus)
	{
		this.projectStatus = projectStatus;
	}

	public Integer getProjectStatus()
	{
		return projectStatus;
	}

	public void setProjectNo(String projectNo)
	{
		this.projectNo = projectNo;
	}

	public String getProjectNo()
	{
		return projectNo;
	}

	public void setProjectInventor(String projectInventor)
	{
		this.projectInventor = projectInventor;
	}

	public String getProjectInventor()
	{
		return projectInventor;
	}

	public void setMaterials(Set<ModelProjectMaterial> materials)
	{
		this.materials = materials;
	}

	public Set<ModelProjectMaterial> getMaterials()
	{
		return materials;
	}

	public void setProcessForms(Set<ModelProjectProcess> processForms)
	{
		this.processForms = processForms;
	}

	public Set<ModelProjectProcess> getProcessForms()
	{
		return processForms;
	}

	public void setProcessEvents(Set<ModelProjectEvent> processEvents)
	{
		this.processEvents = processEvents;
	}

	public Set<ModelProjectEvent> getProcessEvents()
	{
		return processEvents;
	}

	public void setCurrentProcess(ModelProjectProcess currentProcess)
	{
		this.currentProcess = currentProcess;
	}

	public ModelProjectProcess getCurrentProcess()
	{
		return currentProcess;
	}

	public void setProjectPostTime(Date projectPostTime)
	{
		this.projectPostTime = projectPostTime;
	}

	public Date getProjectPostTime()
	{
		return projectPostTime;
	}

	public void setSuspendReason(String suspendReason)
	{
		this.suspendReason = suspendReason;
	}

	public String getSuspendReason()
	{
		return suspendReason;
	}

	public void setArchived(Integer archived)
	{
		this.archived = archived;
	}

	public Integer getArchived()
	{
		return archived;
	}

	public void setCondVO(VoProjectCond condVO)
	{
		this.condVO = condVO;
	}

	public VoProjectCond getCondVO()
	{
		return condVO;
	}

	public void setCondYearMatch(String condYearMatch)
	{
		this.condYearMatch = condYearMatch;
	}

	public String getCondYearMatch()
	{
		return condYearMatch;
	}

	public void setProjectReferralName(String projectReferralName)
	{
		this.projectReferralName = projectReferralName;
	}

	public String getProjectReferralName()
	{
		if (this.projectReferral != null)
		{
			return this.projectReferral.getUsername();
		}
		
		return projectReferralName;
	}

	public void setSuspendTime(Date suspendTime)
	{
		this.suspendTime = suspendTime;
	}

	public Date getSuspendTime()
	{
		return suspendTime;
	}

	public void setRelevantPersonIncluded(boolean isRelevantPersonIncluded)
	{
		this.isRelevantPersonIncluded = isRelevantPersonIncluded;
	}

	public boolean isRelevantPersonIncluded()
	{
		return isRelevantPersonIncluded;
	}

}
